package com.hfut.eeg.service;

import com.hfut.eeg.common.component.EEGThread;
import com.hfut.eeg.common.component.EEGcache;
import com.hfut.eeg.common.util.BlobListTrans;
import com.hfut.eeg.dao.EEGGuideMapper;
import com.hfut.eeg.dto.EEGTrans;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

/**
 * @author 梁琦
 * @program: eeg
 * @Package com.hfut.eeg.service
 * @Description: TODO
 * @date 2019-12-03 15:57
 */
@Service
@Scope("singleton")
public class EEGGuideService {

    private static final Logger LOGGER = LoggerFactory.getLogger(EEGGuideService.class);

    @Autowired
    private EEGGuideMapper eegGuideMapper;

    @Autowired
    private EEGcache eeGcache;

    @Value("${eeg.channelNum}")
    private int channelNum;

    //更新single_guide表
    public int updateSingleGuide(HashMap eegTrans){
        return eegGuideMapper.updateSingleGuide(eegTrans);
    }

    /**
    * 插入single_guide表
    */
    public synchronized int insertSingleGuide(ArrayList<ArrayList>cache,String eegId){
        //数据有效性检验
        if(cache==null || cache.size()<16 || eegId==null){
            LOGGER.error("插入single_guide表时未通过数据检验");
            return -1;
        }
        if(cache.get(0).size()<500){
            LOGGER.error("SingleGuide数据量小于1s");
            return -1;
        }
        //获取当前数据段
        int order = getSingleGuideLatestSequence(eegId);
        int storeSize = 0;

        HashMap<String,Object> getReq = new HashMap<>();
        getReq.put("eegId",eegId);
        getReq.put("sequence",order);
        EEGTrans trans = eegGuideMapper.getSingleGuide(getReq);

        HashMap<String,Object> map = new HashMap<>();
        String []labels = eeGcache.getLabels();

        //解析blob数据，确定数据库中存储数据的数据量
        ArrayList<ArrayList> stores = BlobListTrans.transEEGTransToList(trans);
        if(stores==null || stores.size()==0){
            stores = new ArrayList<>();
            storeSize = -1;
        }else {
            storeSize = stores.get(0).size()/500;
        }

        //表示数据库中没有相关信息，要插入数据库
        if(storeSize >= 10 || storeSize<0){
            for (int i = 0; i<eeGcache.getNchannel(); i++){
                map.put(labels[i],cache.get(i));
            }
            map.put("eegId",eegId);
            map.put("Id",System.currentTimeMillis());
            map.put("sequence",order+1);
            ArrayList list = (ArrayList) map.get(labels[0]);
            LOGGER.info("SingleEEG此时向数据库插入的数据量："+list.size());
            return eegGuideMapper.insertSingleGuide(map);
        }else {
            //更新数据库
            for (int i = 0; i<eeGcache.getNchannel(); i++){
                stores.get(i).addAll(cache.get(i));
                map.put(labels[i],stores.get(i));
            }
            map.put("eegId",eegId);
            map.put("sequence",order);
            ArrayList list = (ArrayList) map.get(labels[0]);
            LOGGER.info("SingleEEG此时向数据库更新的数据量: "+list.size());
            return eegGuideMapper.updateSingleGuide(map);
        }
    }

    /**
    * 获取single_guide表
    */
    public EEGTrans getSingleGuide(String eegId,int order){
        HashMap<String,Object> getReq = new HashMap<>();
        getReq.put("eegId",eegId);
        getReq.put("sequence",order);
        return eegGuideMapper.getSingleGuide(getReq);
    }

    //
    /**
    * 更新all_guide表
    */
    public int updateAllGuide(HashMap eegTrans){
        return eegGuideMapper.updateAllGuide(eegTrans);
    }

    //
    /**
    * 插入all_guide表
    */
    public synchronized int insertAllGuide(ArrayList<ArrayList>cache,String eegId){
        //数据有效性检验
        if(cache==null || cache.size()<16 || eegId==null){
            LOGGER.error("插入all_guide表时未通过数据检验");
            return -1;
        }
        if(cache.get(0).size()<500){
            LOGGER.error("AllGuide数据量小于1s");
            return -1;
        }
        //获取当前数据段
        int order = getAllGuideLatestSequence(eegId);
        int storeSize = 0;

        HashMap<String,Object> getReq = new HashMap<>();
        getReq.put("eegId",eegId);
        getReq.put("sequence",order);
        EEGTrans trans = eegGuideMapper.getAllGuide(getReq);

        HashMap<String,Object> map = new HashMap<>();
        String []labels = eeGcache.getLabels();

        //解析blob数据，确定数据库中存储数据的数据量
        ArrayList<ArrayList> stores = BlobListTrans.transEEGTransToList(trans);
        if(stores==null || stores.size()==0){
            stores = new ArrayList<>();
            storeSize =-1;
        }else {
            storeSize = stores.get(0).size()/500;
        }

        //表示数据库中没有相关信息，要插入数据库
        if(storeSize >= 10 || storeSize<0){
            for (int i = 0; i<eeGcache.getNchannel(); i++){
                map.put(labels[i],cache.get(i));
            }
            map.put("eegId",eegId);
            map.put("Id",System.currentTimeMillis());
            map.put("sequence",order+1);
            ArrayList list = (ArrayList) map.get(labels[0]);
            LOGGER.info("AllEEG此时向数据库插入的数据量："+list.size());
            return eegGuideMapper.insertAllGuide(map);
        }else {
            //更新数据库
            for (int i = 0; i<eeGcache.getNchannel(); i++){
                stores.get(i).addAll(cache.get(i));
                map.put(labels[i],stores.get(i));
            }
            map.put("sequence",order);
            map.put("eegId",eegId);
            ArrayList list = (ArrayList) map.get(labels[0]);
            LOGGER.info("AllEEG此时向数据库更新的数据量: "+list.size());
            return eegGuideMapper.updateAllGuide(map);
        }
    }

    //
    /**
    * 获取all_guide表
    */
    public EEGTrans getAllGuide(String eegId,int order){
        HashMap<String,Object> getReq = new HashMap<>();
        getReq.put("eegId",eegId);
        getReq.put("sequence",order);
        return eegGuideMapper.getAllGuide(getReq);
    }

    /**
    * 获取最新单导数据的数据段序号
    */
    public int getSingleGuideLatestSequence(String eegId){
        Integer sequence = eegGuideMapper.getSingleGuideLatestSequence(eegId);
        return sequence==null?0:sequence;
    }

    /**
     * 获取最新均导数据的数据段序号
     */
    public int getAllGuideLatestSequence(String eegId){
        Integer sequence = eegGuideMapper.getAllGuideLatestSequence(eegId);
        return sequence==null?0:sequence;
    }

    /**
    * @Description: 获取分段单导数据
    * @param patientId 病人ID order 开始数据段位置  num数据段数量
    * @return ArrayList<ArrayList> 单导数据
    * @author 梁琦
    * @date 2019-12-30 20:19
    * @throws
    */
    public ArrayList<ArrayList> getSingleGuideBySeg(String patientId, int order, int num){
        HashMap<String,Object> map = new HashMap<>();
        map.put("patientId",patientId);
        ArrayList<Integer> list = new ArrayList<>();
        for (int i=order;i<order+num;i++){
            list.add(i);
        }
        map.put("sequence",list);
        List<EEGTrans> eegTrans = eegGuideMapper.getSingleGuideBySeg(map);
        if(eegTrans==null || eegTrans.size()==0){
            return null;
        }
        return listsToArr(eegTrans);
    }

    /**
     * @Description: 获取分段均导数据
     * @param patientId 病人ID order 开始数据段位置  num数据段数量
     * @return ArrayList<ArrayList> 均导数据
     * @author 梁琦
     * @date 2019-12-30 20:19
     * @throws
     */
    public ArrayList<ArrayList> getAllGuideBySeg(String patientId,int order,int num){
        HashMap<String,Object> map = new HashMap<>();
        map.put("patientId",patientId);
        ArrayList<Integer> list = new ArrayList<>();
        for (int i=order;i<order+num;i++){
            list.add(i);
        }
        map.put("sequence",list);
        List<EEGTrans> eegTrans =eegGuideMapper.getAllGuideBySeg(map);
        if(eegTrans==null || eegTrans.size()==0){
            return null;
        }
        return listsToArr(eegTrans);
    }

    private ArrayList<ArrayList> listsToArr(List<EEGTrans> list){
        if(list==null ||list.size()==0){
            return null;
        }
        ArrayList<ArrayList>result = new ArrayList<>();
        for (int i=0;i<channelNum;i++){
            result.add(new ArrayList());
        }
        for (EEGTrans trans : list) {
            ArrayList<ArrayList> tmp = BlobListTrans.transEEGTransToList(trans);
            for (int j = 0;tmp!=null&& j < tmp.size(); j++) {
                result.get(j).addAll(tmp.get(j));
            }
        }
        return result;
    }

    public int insertAllList(List<EEGTrans> list){
        return eegGuideMapper.insertAllList(list);
    }

    public int insertSingleList(List<EEGTrans> list){
        return eegGuideMapper.insertSingleList(list);
    }
}
